package cc.siyecao.mapper.wrapper;

import cc.siyecao.mapper.Criteria;
import cc.siyecao.mapper.conditions.Compare;
import cc.siyecao.mapper.conditions.Condition;
import cc.siyecao.mapper.conditions.StringCompare;
import cc.siyecao.mapper.conditions.StringCondition;
import cc.siyecao.mapper.enums.SqlKeyword;
import cc.siyecao.mapper.enums.SqlLike;
import cc.siyecao.mapper.provider.entity.EntityColumn;

import java.util.Collection;
import java.util.List;

public abstract class AbstractCompareWrapper<W, R, T> extends EntityWrapper<W, T> implements Compare<W, R, T>, Condition<W, R> {

    @Override
    public W eq(boolean condition, EntityColumn column, Object val) {
        return addCondition( condition, column, SqlKeyword.EQ, val );
    }

    @Override
    public W eq(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.EQ, val );
    }

    @Override
    public W ne(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.NE, val );
    }

    @Override
    public W gt(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.GT, val );
    }

    @Override
    public W ge(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.GE, val );
    }

    @Override
    public W lt(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.LT, val );
    }

    @Override
    public W le(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.LE, val );
    }

    @Override
    public W like(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.LIKE, val, SqlLike.DEFAULT );
    }

    @Override
    public W notLike(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.NOT_LIKE, val, SqlLike.DEFAULT );
    }

    @Override
    public W notLikeLeft(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.NOT_LIKE, val, SqlLike.LEFT );
    }

    @Override
    public W notLikeRight(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.NOT_LIKE, val, SqlLike.RIGHT );
    }

    @Override
    public W likeLeft(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.LIKE, val, SqlLike.LEFT );
    }

    @Override
    public W likeRight(boolean condition, R column, Object val) {
        return addCondition( condition, column, SqlKeyword.LIKE, val, SqlLike.RIGHT );
    }

    @Override
    public W between(boolean condition, R column, Object val1, Object val2) {
        return addCondition( condition, column, SqlKeyword.BETWEEN, val1, val2 );
    }

    @Override
    public W notBetween(boolean condition, R column, Object val1, Object val2) {
        return addCondition( condition, column, SqlKeyword.NOT_BETWEEN, val1, val2 );
    }

    @Override
    public W isNull(boolean condition, EntityColumn column) {
        return addCondition( condition, column, SqlKeyword.IS_NULL );
    }

    @Override
    public W isNull(boolean condition, R column) {
        return addCondition( condition, column, SqlKeyword.IS_NULL );
    }

    @Override
    public W isNotNull(boolean condition, R column) {
        return addCondition( condition, column, SqlKeyword.IS_NOT_NULL );
    }

    @Override
    public W in(boolean condition, R column, Collection<?> coll) {
        return addCondition( condition, column, SqlKeyword.IN, coll );
    }

    @Override
    public W in(boolean condition, R column, Object... values) {
        return addCondition( condition, column, SqlKeyword.IN, values );
    }

    @Override
    public W notIn(boolean condition, R column, Collection<?> coll) {
        return addCondition( condition, column, SqlKeyword.NOT_IN, coll );
    }

    @Override
    public W notIn(boolean condition, R column, Object... values) {
        return addCondition( condition, column, SqlKeyword.NOT_IN, values );
    }

    @Override
    public W eq(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.EQ, val );
    }

    @Override
    public W ne(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.NE, val );
    }

    @Override
    public W gt(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.GT, val );
    }

    @Override
    public W ge(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.GE, val );
    }

    @Override
    public W lt(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.LT, val );
    }

    @Override
    public W le(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.LE, val );
    }

    @Override
    public W like(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.LIKE, val, SqlLike.DEFAULT );
    }

    @Override
    public W notLike(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.NOT_LIKE, val, SqlLike.DEFAULT );
    }

    @Override
    public W notLikeLeft(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.NOT_LIKE, val, SqlLike.LEFT );
    }

    @Override
    public W notLikeRight(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.NOT_LIKE, val, SqlLike.RIGHT );
    }

    @Override
    public W likeLeft(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.LIKE, val, SqlLike.LEFT );
    }

    @Override
    public W likeRight(boolean condition, String column, Object val) {
        return addCondition( condition, column, SqlKeyword.LIKE, val, SqlLike.RIGHT );
    }

    @Override
    public W between(boolean condition, String column, Object val1, Object val2) {
        return addCondition( condition, column, SqlKeyword.BETWEEN, val1, val2 );
    }

    @Override
    public W notBetween(boolean condition, String column, Object val1, Object val2) {
        return addCondition( condition, column, SqlKeyword.NOT_BETWEEN, val1, val2 );
    }

    @Override
    public W isNull(boolean condition, String column) {
        return addCondition( condition, column, SqlKeyword.IS_NULL );
    }

    @Override
    public W isNotNull(boolean condition, String column) {
        return addCondition( condition, column, SqlKeyword.IS_NOT_NULL );
    }

    @Override
    public W in(boolean condition, String column, Collection<?> coll) {
        return addCondition( condition, column, SqlKeyword.IN, coll );
    }

    @Override
    public W in(boolean condition, String column, Object... values) {
        return addCondition( condition, column, SqlKeyword.IN, values );
    }

    @Override
    public W notIn(boolean condition, String column, Collection<?> coll) {
        return addCondition( condition, column, SqlKeyword.NOT_IN, coll );
    }

    @Override
    public W notIn(boolean condition, String column, Object... values) {
        return addCondition( condition, column, SqlKeyword.NOT_IN, values );
    }

    @Override
    public Criteria getCriteria() {
        Criteria criteria;
        if (criterias.size() == 0) {
            criteria = new Criteria( currentType.getStringValue() );
            criterias.add( criteria );
        } else {
            criteria = criterias.get( criterias.size() - 1 );
            if (criteria == null || !criteria.getType().equals( currentType.getStringValue() )) {
                criteria = new Criteria( currentType.getStringValue() );
                criterias.add( criteria );
            }
        }
        return criteria;
    }

    @Override
    public List<Criteria> getCriterias() {
        return criterias;
    }

}
